home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr27 / p2_10.zip / PAGE2.C next >
C/C++ Source or Header  |  1993-05-09  |  9KB  |  354 lines

  1. /*
  2.  * PAGE2 - program to print files on both sides of the paper
  3.  *
  4.  * Usage: PAGE2 /m:margin /f /b /r file
  5.  *
  6.  * /m:margin Allows a margin to be specified: positive values add that
  7.  *           many spaces at the start of each line, negative values can
  8.  *           also be used to trim leading spaces. WARNING: negative
  9.  *           values cause ANY leading characters to be trimmed, so if too
  10.  *           big a value is used, data may be lost
  11.  * /f        Print only the front (odd numbered) pages
  12.  * /b        Print only the back (even numbered) pages - only one of /f or /b
  13.  *           should be given, if both are given the last one will be the one
  14.  *           used.
  15.  * /r        Print back pages in reverse order - this is intended for use on
  16.  *           laser printers where the printout of the front pages produces
  17.  *           a stack of paper that is put back in to the printer. If a
  18.  *           tractor feed printer is in use, the /r option should not be used
  19.  *           since the order of printing is the same for both front and back.
  20.  *
  21.  * This program creates a temporary file to hold the back page information,
  22.  * it will check both the TEMP and TMP environment variables looking for
  23.  * a directory to use. Use of a ramdisk will speed things up, although
  24.  * make sure there is enough space to hold the temporary file, it will be
  25.  * about half the size of the input file.
  26.  *
  27.  * Revision History:
  28.  *
  29.  * V1.0   11/14/91 - David goodenough   Initial release
  30.  *
  31.  * This code is released to the public domain, you are permitted to distribute
  32.  * this freely, and modify it as necessary to suit you own needs. However if
  33.  * you distribyte a revised copy, this entire header message must remain
  34.  * intact and any changes should be clearly marked as your own work.
  35.  *
  36.  * If you find this useful I'd like to hear from you. Also I'd like any bug
  37.  * reports you come up with, so that I can fix them. I can be reached via
  38.  * E-mail at:
  39.  *
  40.  * RIME:        ->COCONINO - use the PROGRAMR conference,
  41.  *                              send to David Goodenough
  42.  * Fidonet:     David Goodenough at 1:125/28
  43.  * GEnie:       DAVID-CPM
  44.  * CI$:         >INTERNET:dg%pallio.UUCP@cs.sfsu.edu
  45.  * UUCP:        pallio!dg
  46.  * Internet:    dg%pallio.UUCP@cs.sfsu.edu
  47.  *
  48.  * or if you can't get any of the above to work, a postcard to:
  49.  *
  50.  *              David Goodenough
  51.  *              1236 15th. Ave.
  52.  *              San Francisco, CA
  53.  *              94122
  54.  *
  55.  * would be nice. Thanks!
  56.  */
  57.  
  58. static char copyright[] =
  59. "(C) Copyright 1991, David Goodenough. All rights reserved.";
  60.  
  61. #include        <stdio.h>
  62. #include        <stdlib.h>
  63. #include        <clib.h>
  64.  
  65. #define         PRINT       0
  66. #define         SAVE        1
  67. #define         BOTH        0
  68. #define         FRONT       1
  69. #define         BACK        2
  70.  
  71. struct _page_
  72.  {
  73.     struct _page_ *_next;
  74.     long _pos;
  75.     int _size;
  76.  };
  77.  
  78. struct _page_ *back = (struct _page_ *) NULL;
  79. struct _page_ *curr;
  80.  
  81. int target;
  82. int eofseen = FALSE;
  83. int reverse = FALSE;
  84. int margin = 0;
  85. int p1 = 0;
  86. int p2 = 0;
  87. int mode = BOTH;
  88. FILE *ifp, *tfp;
  89.  
  90. main(n, a)
  91. char **a;
  92.  {
  93.     int i;
  94.     int ch;
  95.     char *cp;
  96.     struct _page_ *work;
  97.     char tmpname[256];
  98.  
  99.     if (n >= 2)
  100.      {
  101.         cp = a[1];
  102.         if (*cp == '/' || *cp == '-')
  103.          {
  104.             a++;
  105.             n--;
  106.             if ((ch = *++cp | 0x20) == 'f')
  107.               mode = FRONT;
  108.             else if (ch == 'b')
  109.               mode = BACK;
  110.             else if (ch == 'r')
  111.               reverse = TRUE;
  112.             else if (ch == 'm' && *++cp == ':')
  113.               margin = atoi(++cp);
  114.             else
  115.              {
  116.                 printf("Usage: PAGE2 [/m:margin /f /b /r] file\n");
  117.                 exit(1);
  118.              }
  119.          }
  120.      }
  121.     if (n < 2)
  122.      {
  123.         printf("Usage: PAGE2 [/m:margin /f /b /r] file\n");
  124.         exit(1);
  125.      }
  126.     if ((ifp = fopen(a[1], "rb")) == (FILE *) NULL)
  127.      {
  128.         printf("Error: can't open %s\n", a[1]);
  129.         exit(2);
  130.      }
  131.     if (mode != FRONT)
  132.      {
  133.         if (((cp = getenv("TEMP")) != (char *) NULL ||
  134.                                 (cp = getenv("TMP")) != (char *) NULL) && *cp)
  135.          {
  136.             strcpy(tmpname, cp);
  137.             namefix(tmpname);
  138.             if (tmpname[strlen(tmpname) - 1] != '\\')
  139.               strcat(tmpname, "\\");
  140.          }
  141.         else
  142.           tmpname[0] = 0;
  143.         strcat(tmpname, "$PAGE$.TMP");
  144.         if ((tfp = fopen(tmpname, "w+")) == (FILE *) NULL)
  145.          {
  146.             printf("Error: can't creat temp file\n");
  147.             exit(3);
  148.          }
  149.      }
  150.     eofseen = FALSE;
  151.     prinit(FALSE);
  152.     for (;;)
  153.      {
  154.         target = PRINT;
  155.         sendpage();
  156.         makedata();
  157.         if (eofseen)
  158.           break;
  159.         target = SAVE;
  160.         sendpage();
  161.         if (eofseen)
  162.           break;
  163.      }
  164.     if (mode != FRONT)
  165.      {
  166.         if (back == (struct _page_ *) NULL)
  167.          {
  168.             printf("No back pages to print\n");
  169.             exit(0);
  170.          }
  171.         printf("Front pages done, please reload paper\nHit <ENTER> when ready: ");
  172.         while ((xkb() & 255) != 13)
  173.           ;
  174.         printf("\n");
  175.         if (p1 != p2)
  176.           prchar('\f');
  177.         for (work = back; work != (struct _page_ *) NULL; work = work->_next)
  178.          {
  179.             fseek(tfp, work->_pos, 0L);
  180.             for (i = 0; i < work->_size; i++)
  181.              {
  182.                 if ((ch = getc(tfp)) == EOF)
  183.                   break;
  184.                 prchar(ch);
  185.              }
  186.          }
  187.      }
  188.     printf("Done.\n");
  189.     fclose(ifp);
  190.     if (mode != FRONT)
  191.      {
  192.         fclose(tfp);
  193.         unlink(tmpname);
  194.      }
  195.     exit(0);
  196.  }
  197.  
  198. sendpage()
  199.  {
  200.     int lines;
  201.     int chars;
  202.     int ch;
  203.  
  204.     lines = chars = 0;
  205.     while (lines < 66)
  206.      {
  207.         if ((ch = getmarg()) == EOF)
  208.          {
  209.             eofseen = TRUE;
  210.             if (lines == 0 && chars == 0)
  211.               return;
  212.             else
  213.               ch = '\f';
  214.          }
  215.         switch (ch)
  216.          {
  217.             case '\r':
  218.               chars = 0;
  219.             break;
  220.             case '\n':
  221.               lines++;
  222.             break;
  223.             case '\b':
  224.               if (chars >= margin)
  225.                 chars--;
  226.             break;
  227.             case '\f':
  228.               lines = 66;
  229.             break;
  230.             default:
  231.              {
  232.                 if (++chars == 80)
  233.                  {
  234.                     chars = 0;
  235.                     lines++;
  236.                  }
  237.              }
  238.             break;
  239.          }
  240.         savech(ch);
  241.      }
  242.     if (target == PRINT)
  243.       p1++;
  244.     else
  245.       p2++;
  246.  }
  247.  
  248. savech(ch)
  249.  {
  250.     if (target == PRINT)
  251.      {
  252.         if (mode != BACK)
  253.           prchar(ch);
  254.      }
  255.     else if (mode != FRONT)
  256.      {
  257.         putc(ch, tfp);
  258.         curr->_size++;
  259.      }
  260.  }
  261.  
  262. makedata()
  263.  {
  264.     struct _page_ *work;
  265.  
  266.     if ((work = (struct _page_ *) malloc(sizeof(struct _page_))) ==
  267.                                     (struct _page *) NULL)
  268.      {
  269.         eofseen = TRUE;
  270.         printf("Out of memory\n");
  271.         return;
  272.      }
  273.     if (reverse || back == (struct _page_ *) NULL)
  274.      {
  275.         work->_next = back;
  276.         curr = back = work;
  277.      }
  278.     else
  279.      {
  280.         for (curr = back; curr->_next != (struct _page_ *) NULL;
  281.                                                         curr = curr->_next)
  282.           ;
  283.         curr->_next = work;
  284.         curr = work;
  285.         curr->_next = (struct _page_ *) NULL;
  286.      }
  287.     curr->_pos = ftell(tfp);
  288.     curr->_size = 0;
  289.  }
  290.  
  291. getmarg()
  292.  {
  293.     int ch;
  294.     static int pos = -1;
  295.     static int add = 0;
  296.     static int swallow = 0;
  297.  
  298.     if (pos == -1)
  299.      {
  300.         if (margin > 0)
  301.           add = margin;
  302.         else if (margin < 0)
  303.           swallow = -margin;
  304.         pos = 0;
  305.      }
  306.     for (;;)
  307.      {
  308.         if (add)
  309.          {
  310.             add--;
  311.             return(' ');
  312.          }
  313.         switch (ch = getc(ifp))
  314.          {
  315.             case EOF:
  316.             case '\n':
  317.             case '\f':
  318.               return(ch);
  319.             case '\r':
  320.              {
  321.                 pos = -1;
  322.                 return(ch);
  323.              }
  324.             case '\b':
  325.              {
  326.                 if (pos)
  327.                   pos--;
  328.                 return(ch);
  329.              }
  330.             case '\t':
  331.              {
  332.                 add = 8 - (pos & 7);
  333.                 pos += add;
  334.                 while (add && swallow)
  335.                  {
  336.                     add--;
  337.                     swallow--;
  338.                  }
  339.                 continue;
  340.              }
  341.             default:
  342.              {
  343.                 pos++;
  344.                 if (swallow)
  345.                  {
  346.                     swallow--;
  347.                     continue;
  348.                  }
  349.                 return(ch);
  350.              }
  351.          }
  352.      }
  353.  }
  354.